package com.songlanyun.modules.order.service.impl.createorder;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.songlanyun.common.enums.GoodsConstant;
import com.songlanyun.common.enums.MemberConstant;
import com.songlanyun.common.enums.OrderConstant;
import com.songlanyun.common.exception.RRException;
import com.songlanyun.common.utils.BeanUtil;
import com.songlanyun.common.utils.custom.MathUtils;
import com.songlanyun.modules.exception.GoodsExceptionEnum;
import com.songlanyun.modules.exception.OrderException;
import com.songlanyun.modules.inter.ISaleEntity;
import com.songlanyun.modules.memberbill.entity.GiveBalanceDTO;
import com.songlanyun.modules.order.dao.OrderDao;
import com.songlanyun.modules.order.entity.Order;
import com.songlanyun.modules.order.entity.SaleServiceOrderContacts;
import com.songlanyun.modules.order.model.dto.SubmitChildOrderDTO;
import com.songlanyun.modules.order.model.dto.SubmitOrderDTO;
import com.songlanyun.modules.order.model.dto.SubmitShopOrderDTO;
import com.songlanyun.modules.order.model.vo.*;
import com.songlanyun.modules.order.service.ChildOrderService;
import com.songlanyun.modules.order.service.CreateOrderService;
import com.songlanyun.modules.order.service.SaleServiceOrderContactsService;
import com.songlanyun.modules.payorder.entity.PayOrder;
import com.songlanyun.modules.payorder.service.PayOrderService;
import com.songlanyun.modules.saleconfig.entity.SaleConfig;
import com.songlanyun.modules.saleconfig.service.SaleConfigService;
import com.songlanyun.modules.servicegoods.entity.ServiceGoods;
import com.songlanyun.modules.servicegoods.service.ServiceGoodsService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 服务商品订单构单与下单
 */
@Service("serviceGoodsCreateOrderService")
public class ServiceGoodsCreateOrderServiceImpl extends ServiceImpl<OrderDao, Order> implements CreateOrderService {


    @Resource(name="createOrderService")
    private CreateOrderService createOrderService;

    @Autowired
    private ServiceGoodsService serviceGoodsService;



    @Autowired
    private PayOrderService payOrderService;



    @Autowired
    private ChildOrderService childOrderService;

    @Autowired
    private SaleConfigService saleConfigService;

    @Autowired
    private SaleServiceOrderContactsService saleServiceOrderContactsService;
    /**
     * 构建下单页数据
     *
     * @param userId
     * @param dto
     * @return
     */
    @Override
    public SubmitOrderVo buildSubmitOrder(Long userId, SubmitOrderDTO dto) {
        SubmitOrderVo vo = initSubmitOrderVo(userId, dto);
        List<SubmitShopOrderVo> shopOrderVoList = null;
        shopOrderVoList = serviceOrderBuild(userId, vo, dto);

        BigDecimal totalMoney = MathUtils.setScale(shopOrderVoList.stream().mapToDouble(c -> c.getTotalAmount().doubleValue()).sum());
        BigDecimal totalReducedMoney = MathUtils.setScale(shopOrderVoList.stream().mapToDouble(c -> c.getTotalReduced().doubleValue()).sum());

        vo.setShopOrders(shopOrderVoList);
        vo.setAreaFeature(GoodsConstant.AreaFeature.GENERAL);
        vo.setTotalMoney(totalMoney);
        vo.setTotalReduced(totalReducedMoney);
        return vo;
    }

    /**
     * 会员下单服务
     *
     * @param userId
     * @param dto
     * @return
     */

    @Override
    public PayOrder createPayOrder(Long userId, SubmitOrderDTO dto) {
        /**
         * 构建下单数据
         */
        SubmitOrderVo submitOrderVo = this.buildSubmitOrder(userId, dto);
        /**
         *
         * 提取商品图片为了待支付订单
         */
        List<String> goodsImages = new ArrayList<>();
        submitOrderVo.getShopOrders().forEach(o -> {
            o.getItems().forEach(c -> {
                goodsImages.add(c.getGoodsCover());
            });
        });

        long expiredTimestamp = saleConfigService.getExpiredTimestamp();
        /**
         * 创建支付订单（1，用来做合单，2用来做支付）
         */
        PayOrder payOrder = payOrderService.initPayOrderForSale(userId, submitOrderVo.getTotalMoney(), submitOrderVo.getTotalReduced(), OrderConstant.PayMode.BALANCE, OrderConstant.OrderType.SERVICE_ORDER, goodsImages, expiredTimestamp,submitOrderVo.getPlatformCoupon(),submitOrderVo.getAreaFeature());
        List<SubmitShopOrderVo> shopOrders = submitOrderVo.getShopOrders();
        for (SubmitShopOrderVo shopOrder : shopOrders) {
            /**
             * 开始创建商家订单
             */
            Order order = createOrder(userId, payOrder, submitOrderVo, shopOrder);
            /**
             * 创建订单的钥匙
             */
            createOrderKey(order);
            /**
             * 设置服务订单联系人信息
             */
            createServiceContacts(order,submitOrderVo);

            List<SubmitChildOrderVo> items = shopOrder.getItems();
            for (SubmitChildOrderVo childOrderVo : items) {
                /**
                 * 创建订单的商品子订单明细
                 */
                childOrderService.create(order, childOrderVo);
            }
        }
        return payOrder;
    }

    @Override
    public void thirdCanSaleCheck(SubmitOrderVo vo) {

    }

    /**
     * 设置服务订单联系人信息
     * @param order
     * @param submitOrderVo
     */
    private void createServiceContacts(Order order,SubmitOrderVo submitOrderVo)
    {
        SaleServiceOrderContacts saleServiceOrderContacts = new SaleServiceOrderContacts();
        SubmitServiceOrderContactsVo serviceContacts = submitOrderVo.getServiceContacts();
        saleServiceOrderContacts.setContacts(serviceContacts.getContacts());
        saleServiceOrderContacts.setMobile(serviceContacts.getMobile());
        saleServiceOrderContacts.setGender(MemberConstant.GenderType.getByCode(serviceContacts.getGender()));
        saleServiceOrderContacts.setOrderId(order.getId());
        saleServiceOrderContactsService.create(saleServiceOrderContacts);
    }

    /**
     * 内部调用初始化订单的基础数据================================================
     *
     * @param userId
     * @param dto
     * @return
     */
    @Override
    public SubmitOrderVo initSubmitOrderVo(Long userId, SubmitOrderDTO dto) {
        //下单时一定要选择店铺====================================================
        if (dto.getShopOrders().size() == 0) {
            throw new RRException(OrderException.ORDER_NOT_SHOP);
        }

        SubmitOrderVo vo = new SubmitOrderVo();
        vo.setOrderType(dto.getOrderType());
        //活动内类型设置
        vo.setMarketingType(0);
        vo.setUserId(userId);
        //客户端设置
        vo.setChanelType(dto.getChanelType());
        //是否是来源购物车
        vo.setIsCart(false);
        //设置物流模式
        vo.setShipmentMode(2);
        SubmitServiceOrderContactsVo submitServiceOrderContactsVo = new SubmitServiceOrderContactsVo();
        BeanUtil.copyPropertiesIgnoreNull(dto.getServiceContacts(),submitServiceOrderContactsVo);
        vo.setServiceContacts(submitServiceOrderContactsVo);
        return vo;
    }

    @Override
    public BigDecimal processFreight(Long shopId, SubmitOrderReceiptVo receipt, List<SubmitChildOrderVo> childOrderVoList) {
        return BigDecimal.ZERO;
    }

    /**
     * 重构初始化构造提交商家订单vo
     * @param userId
     * @param dto
     * @param o
     * @return
     */
    @Override
    public SubmitShopOrderVo initBuildSubmitShopOrderVo(Long userId, SubmitOrderDTO dto, SubmitShopOrderDTO o) {
        return createOrderService.initBuildSubmitShopOrderVo(userId,dto,o);
    }

    /**
     * 重构初始化构造提交商家子订单vo
     *
     * @param saleEntity
     * @param dto
     * @param o
     * @param s
     * @return
     */
    @Override
    public SubmitChildOrderVo initBuildSubmitChildOrderVo(ISaleEntity saleEntity, SubmitOrderDTO dto, SubmitShopOrderDTO o, SubmitChildOrderDTO s) {
        SubmitChildOrderVo childOrderVo = new SubmitChildOrderVo();
        childOrderVo.setOrderType(dto.getOrderType());
        ServiceGoods goods = (ServiceGoods) saleEntity;
        if (!goods.isVerify()) {
            //商品审核不通过
            throw new RRException(GoodsExceptionEnum.GOODS_VERIFY_NOT);
        }

        if (!goods.getAdded()) {
            //商品未上架
            throw new RRException(GoodsExceptionEnum.GOODS_NOT_ADDED);
        }
        childOrderVo.setUserCartId(s.getUserCartId());
        childOrderVo.setGoodsId(goods.getId());
        childOrderVo.setGoodsTitle(goods.getTitle());
        childOrderVo.setGoodsShortTitle("");
        childOrderVo.setProxyGoods(false);
        childOrderVo.setGiftType(GoodsConstant.GiftType.NO);
        childOrderVo.setFreightTemplateId(0);
        //如果是下的活动订单这里要设置活动商品
        childOrderVo.setActivityGoodsId(s.getActivityGoodsId());
        childOrderVo.setGoodsCover(goods.getCover());
        childOrderVo.setNum(s.getNum());

        childOrderVo.setFirstCategoryId(goods.getCategoryId());
        childOrderVo.setGoodsCategoryId(goods.getCategoryId());
        return childOrderVo;
    }

    @Override
    public void computeSelectedShopCoupon(Long userId, SubmitShopOrderVo vo, SubmitShopOrderDTO dto) {
        createOrderService.computeSelectedShopCoupon(userId,vo,dto);
    }

    @Override
    public void backStageManagement(GiveBalanceDTO dto) {

    }

    /**
     * 普通订单构单
     *
     * @param userId
     * @param vo
     * @param dto
     * @return
     */
    private List<SubmitShopOrderVo> serviceOrderBuild(Long userId, SubmitOrderVo vo, SubmitOrderDTO dto) {
        return dto.getShopOrders().stream().map(o -> {

            SubmitShopOrderVo shopOrderVo = initBuildSubmitShopOrderVo(userId, dto, o);
            shopOrderVo.setSponsorActivityId(0L);
            shopOrderVo.setActivityId(0L);
            shopOrderVo.setActivityTitle("");

            List<SubmitChildOrderVo> childOrderVoList = o.getItems().stream().map(s -> {
                ServiceGoods goods = serviceGoodsService.loadServiceGoodsByShopIdAndId(o.getShopId(), s.getGoodsId(),true);

                SubmitChildOrderVo childOrderVo = initBuildSubmitChildOrderVo(goods, dto, o, s);
                childOrderVo.setSkuHashCode("");
                childOrderVo.setSkuSetName("");
                childOrderVo.setSkuBarCode(goods.getCode());
                childOrderVo.setGoodsCover(goods.getCover());
                childOrderVo.setSingleGoodsId(0L);
                childOrderVo.setSingleGoodsCode("");
                childOrderVo.setSingleGoodsTitle("");
                childOrderVo.setUnit("");
                childOrderVo.setStockStatus(0);
                childOrderVo.setAreaFeature(GoodsConstant.AreaFeature.GENERAL);
                //设置重量
                childOrderVo.setWeight(BigDecimal.ZERO);
                childOrderVo.setTotalWeight(BigDecimal.ZERO);
                //设总体积
                childOrderVo.setVolume(BigDecimal.ZERO);
                childOrderVo.setTotalVolume(BigDecimal.ZERO);
                //设总成本
                childOrderVo.setCost(BigDecimal.ZERO);
                childOrderVo.setTotalCost(BigDecimal.ZERO);
                //首页优惠分摊
                childOrderVo.setFirstOrderReduced(BigDecimal.ZERO);
                //计算会员的折扣
                BigDecimal discount = BigDecimal.TEN;
                childOrderVo.setFactPrice(MathUtils.multiplyMulti(2, goods.getSalePrice(), discount, new BigDecimal("0.1")));
                childOrderVo.setSalePrice(goods.getMarketPrice());
                childOrderVo.setMarketPrice(goods.getMarketPrice());
                childOrderVo.setTotalReduced(BigDecimal.ZERO);

                childOrderVo.setTotalPrice(MathUtils.multiply(childOrderVo.getFactPrice(), new BigDecimal(s.getNum())));
                childOrderVo.setOriginalGoodsAmount(MathUtils.multiply(childOrderVo.getSalePrice(), new BigDecimal(s.getNum())));
                childOrderVo.setExchangePoint(BigDecimal.ZERO);
                childOrderVo.setTotalPoint(BigDecimal.ZERO);
                childOrderVo.setServiceCount(goods.getServiceCount());
                childOrderVo.setWelfareItems(StringUtils.join(goods.getWelfareItems(),","));
                childOrderVo.setValidity(goods.getValidity());
                childOrderVo.setAdvanceReservation(goods.getAdvanceReservation());
                childOrderVo.setServiceItems(goods.loadServiceItems());
                return childOrderVo;
            }).collect(Collectors.toList());

            //每家店的订单商品总优惠
            BigDecimal totalReduced = MathUtils.setScale(childOrderVoList.stream().mapToDouble(c -> c.getTotalReduced().doubleValue()).sum());
            //每家店的商品总费用
            BigDecimal totalAmount = MathUtils.setScale(childOrderVoList.stream().mapToDouble(c -> c.getTotalPrice().doubleValue()).sum());

            shopOrderVo.setItems(childOrderVoList);
            shopOrderVo.setAreaFeature(GoodsConstant.AreaFeature.GENERAL);
            // 首单优惠出来之后这里还要加上首单优惠,同时还要分摊给每个子订单
            BigDecimal firstOrderReduced = BigDecimal.ZERO;
            shopOrderVo.setFirstOrderReduced(BigDecimal.ZERO);
            shopOrderVo.setTotalReduced(MathUtils.add(totalReduced, firstOrderReduced));
            //订单总成本
            shopOrderVo.setTotalCost(BigDecimal.ZERO);
            //原商品总价
            shopOrderVo.setOriginalGoodsAmount(MathUtils.setScale(childOrderVoList.stream().mapToDouble(ss -> ss.getOriginalGoodsAmount().doubleValue()).sum()));
            //订单商品总价
            shopOrderVo.setTotalGoodsAmount(totalAmount);
            //订单运费
            shopOrderVo.setTotalFreight(BigDecimal.ZERO);
            //订单总费用
            shopOrderVo.setTotalAmount(totalAmount);
            //订单商品总数
            shopOrderVo.setGoodsNum(childOrderVoList.stream().mapToInt(SubmitChildOrderVo::getNum).sum());
            return shopOrderVo;
        }).collect(Collectors.toList());
    }


    /**
     * 创建订单的钥匙
     *
     * @param order
     */
    @Override
    public void createOrderKey(Order order) {
       createOrderService.createOrderKey(order);
    }

    /**
     * 创建收货地址或自提信息
     *
     * @param order
     * @param vo
     */
    @Override
    public void createOrderReceiving(Order order, SubmitOrderVo vo) {

    }

    /**
     * 创建订单
     *
     * @param userId
     * @param payOrder
     * @param submitOrderVo
     * @param vo
     * @return
     */
    @Override
    public Order createOrder(Long userId, PayOrder payOrder, SubmitOrderVo submitOrderVo, SubmitShopOrderVo vo) {
        return createOrderService.createOrder(userId, payOrder, submitOrderVo, vo);
    }
}
